package com.syni.mdd.yhd.common.all.service.impl;

import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsThirdCodeDao;
import com.syni.mdd.yhd.common.all.entity.BmsDxOrder;
import com.syni.mdd.yhd.common.all.entity.groupBuy.BmsThirdCode;
import com.syni.mdd.yhd.common.all.service.BmsCommonService;
import com.syni.mdd.yhd.common.all.service.BmsThirdCodeService;
import com.syni.mdd.sjb.common.component.utils.redis.utils.RedisTemplateUtils;;
import com.syni.mdd.yhd.common.all.utils.SpecificationUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @className
 * @description TOO
 * @Author cfx
 * @DATE 2019/9/23 10:34
 * @VERSION 1.0
 **/
@Service
public class BmsThirdCodeServiceImpl extends BaseService<BmsThirdCode, Integer> implements BmsThirdCodeService {

    //对于没有订单的券码只锁15分钟
    public final static int LOCK_MIN = 15;

    @Autowired
    BmsThirdCodeDao bmsThirdCodeDao;

    @Override
    public BmsThirdCodeDao getBaseDao() {
        return bmsThirdCodeDao;
    }

    @Override
    public List<String> findCanUseCode(BmsDxOrder bmsDxOrder) {
        Pageable pageable = BmsCommonService.getPageable(1, bmsDxOrder.getGroupBuyNum());
        List<BmsThirdCode> bmsThirdCodes = bmsThirdCodeDao.findByOrderIdAndIsMatch(bmsDxOrder.getId(), Constants.COMMON_FLAG_TRUE_INT,pageable);
        List<String> canUseThirdCodes = new ArrayList<>();
        if(bmsThirdCodes != null && bmsThirdCodes.size() > 0){
            for (BmsThirdCode bmsThirdCode : bmsThirdCodes) {
                canUseThirdCodes.add(bmsThirdCode.getVerNo());
            }
        }
        return canUseThirdCodes;
    }

    /**
     * @Description: 锁库存
     * @Author: cfx
     * @Date: 2019/11/22
     */
    @Override
    public List<BmsThirdCode> checkUseCodeHavingUseNum(Integer businessId,Integer groupBuyId,Integer groupBuyNum) {
        Pageable pageable;
        List<BmsThirdCode> saveBmsThirdCodes = new ArrayList<>();
        String redisKeyPre = Constants.REDIS_KEY_USE_TE_CODE + businessId + ":";
        Set<Integer> ids = new HashSet<>();
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("businessId",businessId);
        conditionMap.put("groupBuyId",groupBuyId);
        conditionMap.put("isMatch",Constants.COMMON_FLAG_FALSE_INT);
        while (saveBmsThirdCodes.size() < groupBuyNum) {
            if(ids.size() > 0){
                conditionMap.put("id_NIN",ids);
            }
            pageable = BmsCommonService.getPageable(1, groupBuyNum - saveBmsThirdCodes.size());
            List<BmsThirdCode> bmsThirdCodes = bmsThirdCodeDao.findAll(new SpecificationUtils(conditionMap),pageable).getContent();
            if (!(bmsThirdCodes != null && bmsThirdCodes.size() > 0)) {
                break;
            }
            for (BmsThirdCode bmsThirdCode : bmsThirdCodes) {
                if (RedisTemplateUtils.getRedisTemplate().opsForValue().
                        setIfAbsent(redisKeyPre + bmsThirdCode.getVerNo(), 1,LOCK_MIN,TimeUnit.MINUTES)) {
                    //bmsThirdCode.setIsMatch(Constants.COMMON_FLAG_TRUE_INT);
                    //bmsThirdCode.setOrderId(bmsDxOrder.getId());
                    saveBmsThirdCodes.add(bmsThirdCode);
                }
                ids.add(bmsThirdCode.getId());
            }
        }
        if(saveBmsThirdCodes.size() == groupBuyNum){
            return saveBmsThirdCodes;
        }
        //释放掉锁的那部分
        for(BmsThirdCode bmsThirdCode : saveBmsThirdCodes){
            if(RedisTemplateUtils.getRedisTemplate().hasKey(redisKeyPre + bmsThirdCode.getVerNo())){
                //释放锁掉的库存
                RedisTemplateUtils.getRedisTemplate().delete(redisKeyPre + bmsThirdCode.getVerNo());
            }
        }
        return null;
    }


    @Override
    public void stockReturn(Integer orderId) {
        List<BmsThirdCode> bmsThirdCodes = bmsThirdCodeDao.findByOrderIdAndIsMatch(orderId,Constants.COMMON_FLAG_TRUE_INT);
        handleReturnLog(bmsThirdCodes);
    }

    @Override
    public void stockReturn(Set<String> verNo,Integer orderId) {
        List<BmsThirdCode> bmsThirdCodes = bmsThirdCodeDao.findByVerNoInAndOrderId(verNo,orderId);
        handleReturnLog(bmsThirdCodes);
    }

    private void handleReturnLog(List<BmsThirdCode> bmsThirdCodes) {
        if(bmsThirdCodes != null && bmsThirdCodes.size() > 0){
            for(BmsThirdCode bmsThirdCode : bmsThirdCodes){
                bmsThirdCode.setOrderId(null);
                bmsThirdCode.setIsMatch(Constants.COMMON_FLAG_FALSE_INT);
                //清空redis
                if(RedisTemplateUtils.getRedisTemplate().hasKey(Constants.REDIS_KEY_USE_TE_CODE + bmsThirdCode.getBusinessId() + ":" + bmsThirdCode.getVerNo())){
                    //释放锁掉的库存
                    RedisTemplateUtils.getRedisTemplate().delete(Constants.REDIS_KEY_USE_TE_CODE + bmsThirdCode.getBusinessId() + ":" + bmsThirdCode.getVerNo());
                }
            }
            bmsThirdCodeDao.saveAll(bmsThirdCodes);
        }
    }
}
